package com.azier.mysql.service;

import com.azier.exception.ServiceException;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.entity.Example;

import java.util.List;

/**
 * Service 基类， 提供常用的 CRUD 及分页方法
 *
 * @author 金建强(ptma@163.com)
 * @version 2015-10-13 21:26.
 */
@Service
public abstract class BaseService<T> {

    @Autowired
    protected Mapper<T> mapper;

    /**
     * 插入
     *
     * @param entity 实体类
     * @return 影响的行数
     * @throws ServiceException 业务出错
     */
    public int insert(T entity) throws ServiceException {
        try {
            return mapper.insert(entity);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 插入，仅保存非 NULL 字段
     *
     * @param entity 实体类
     * @return 影响的行数
     * @throws ServiceException 业务出错
     */
    public int insertSelective(T entity) throws ServiceException {
        try {
            return mapper.insertSelective(entity);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 根据主键更新
     *
     * @param entity 实体类
     * @return 影响的行数
     * @throws ServiceException 业务出错
     */
    public int update(T entity) throws ServiceException {
        try {
            return mapper.updateByPrimaryKey(entity);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 根据主键更新， 仅更新非 NULL 字段
     *
     * @param entity 实体类
     * @return 影响的行数
     * @throws ServiceException 业务出错
     */
    public int updateSelective(T entity) throws ServiceException {
        try {
            return mapper.updateByPrimaryKeySelective(entity);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    public int updateByExampleSelective(T entity, Object example) throws ServiceException {
        try {
            return mapper.updateByExampleSelective(entity, example);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 插入或更新
     *
     * @param entity 实体类
     * @return 影响的行数
     * @throws ServiceException 业务出错
     */
    public int saveOrUpdate(T entity) throws ServiceException {
        try {
            if (!mapper.existsWithPrimaryKey(entity)) {
                return mapper.insert(entity);
            } else {
                return mapper.updateByPrimaryKey(entity);
            }
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 插入或更新， 仅插入或更新非 NULL 字段
     *
     * @param entity 实体类
     * @return 影响的行数
     * @throws ServiceException 业务出错
     */
    public int saveOrUpdateSelective(T entity) throws ServiceException {
        try {
            if (null == mapper.selectByPrimaryKey(entity)) {
                return mapper.insertSelective(entity);
            } else {
                return mapper.updateByPrimaryKeySelective(entity);
            }
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 删除
     *
     * @param entity 实体类
     * @return 影响的行数
     * @throws ServiceException 业务出错
     */
    public int delete(T entity) throws ServiceException {
        try {
            return mapper.deleteByPrimaryKey(entity);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 删除
     *
     * @param key 主键
     * @return 影响的行数
     * @throws ServiceException 业务出错
     */
    public int deleteByPrimaryKey(Object key) throws ServiceException {
        try {
            return mapper.deleteByPrimaryKey(key);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    public void batchDeleteByPrimaryKey(List<?> keys) throws ServiceException {
        try {
            for (Object key : keys) {
                mapper.deleteByPrimaryKey(key);
            }
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 按条件删除
     *
     * @param example 查询条件
     * @return 影响的行数
     * @throws ServiceException 业务出错
     */
    public int deleteByExample(Example example) throws ServiceException {
        try {
            return mapper.deleteByExample(example);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 根据Example条件进行查询总数
     *
     * @return 记录数
     * @throws ServiceException 业务出错
     */
    public int selectCountByExample(Example example) throws ServiceException {
        try {
            return mapper.selectCountByExample(example);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 按主键查询
     *
     * @param key 主键
     * @return 符合条件的实体
     * @throws ServiceException 业务出错
     */
    public T selectByPrimaryKey(Object key) throws ServiceException {
        try {
            return mapper.selectByPrimaryKey(key);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 按主键查询是否存在记录
     *
     * @param key 主键
     * @return 是否有对应的记录
     * @throws ServiceException 业务出错
     */
    public boolean existsWithPrimaryKey(Object key) throws ServiceException {
        try {
            return mapper.existsWithPrimaryKey(key);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 根据给定的实体类的不为Null的属性查询，
     *
     * @param entity 查询实体， 为 null 时全表查询
     * @return 全部实体的集合
     * @throws ServiceException 业务出错
     */
    public List<T> select(T entity) throws ServiceException {
        try {
            return mapper.select(entity);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    public List<T> selectAll() throws ServiceException {
        try {
            return mapper.selectAll();
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 按条件查询
     *
     * @param example 查询条件
     * @return 符合条件的实体集合
     * @throws ServiceException 业务出错
     */
    public List<T> selectByExample(Example example) throws ServiceException {
        try {
            return mapper.selectByExample(example);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 按条件查询单条
     *
     * @param example 查询条件
     * @return 第一个符合条件的实体
     * @throws ServiceException 业务出错
     */
    public T selectOneByExample(Example example) throws ServiceException {
        try {
            List<T> list = mapper.selectByExampleAndRowBounds(example, new RowBounds(0, 1));
            if (null != list && !list.isEmpty()) {
                return list.get(0);
            } else {
                return null;
            }
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }
}
